package com.waterstudio.filedownloader.ext.m3u8.client;

import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.zip.GZIPInputStream;

import javax.Constant;

/**
 * Created by chensuilun on 2019/3/23.
 */
public final class Http implements Client {
    private static final int MAX_REDIRECT = 5;
    private HttpURLConnection connection;
    private String currUrl;
    private InputStream inputStream;
    private boolean isConn;

    public Http(@NonNull Uri uri) {
        this.currUrl = uri.toString();
    }

    @Override
    public void connect() throws IOException {
        if (isConn) {
            return;
        }
        connectInternal();
    }

    private void connectInternal() throws IOException {
        int responseCode;
        int i = 0;
        boolean redirect;
        do {
            this.connection = (HttpURLConnection) new URL(this.currUrl).openConnection();
            this.connection.setConnectTimeout(30000);
            this.connection.setReadTimeout(15000);
            this.connection.setRequestMethod("GET");
            this.connection.setDoInput(true);
            this.connection.setRequestProperty(Constant.HEADER_UA, Constant.UA);
            this.connection.setRequestProperty("Accept", "*/*");
            this.connection.setRequestProperty("Accept-Encoding", "gzip");
            this.connection.connect();
            responseCode = this.connection.getResponseCode();
            redirect = responseCode == 301 || responseCode == 302 || responseCode == 303;
            if (redirect) {
                this.currUrl = this.connection.getHeaderField("Location");
                this.connection.disconnect();
                i++;
            }
            if (i > MAX_REDIRECT) {
                throw new IOException("Error connect to: " + this.currUrl + "  too many redirects");
            }
        } while (redirect);
        if (responseCode == 200 || responseCode == 206) {
            this.isConn = true;
        } else {
            throw new IOException(String.format("Error connect to: %s , %s, %d", this.currUrl, this.connection.getResponseMessage(), this.connection.getResponseCode()));
        }
    }

    @Override
    public boolean isConnected() {
        return this.isConn;
    }

    @Override
    public long getSize() {
        if (!this.isConn) {
            return 0;
        }
        String contentRange = this.connection.getHeaderField("Content-Range");
        String contentLength = this.connection.getHeaderField("Content-Length");
        if (!TextUtils.isEmpty(contentRange)) {
            try {
                return Long.parseLong(contentRange);
            } catch (Exception ignore) {

            }
        }
        if (!TextUtils.isEmpty(contentLength)) {
            try {
                return Long.parseLong(contentLength);
            } catch (Exception ignore) {

            }
        }
        return 0;
    }

    @NonNull
    @Override
    public String getUrl() {
        return this.currUrl;
    }

    @Nullable
    public InputStream getInputStream() throws IOException {
        if (this.inputStream == null && this.connection != null) {
            String str = "gzip";
            if (str.equals(this.connection.getContentEncoding())) {
                this.inputStream = new GZIPInputStream(this.connection.getInputStream());
            } else {
                this.inputStream = this.connection.getInputStream();
            }
        }
        return this.inputStream;
    }


    @Override
    public void close() {
        try {
            if (this.inputStream != null) {
                this.inputStream.close();
            }
        } catch (Exception ignore) {

        } finally {
            if (this.connection != null) {
                this.connection.disconnect();
            }
            this.isConn = false;
        }
    }
}
